// -*-mode:c++; coding:utf-8-*-

#include "column_name_parser.hpp"

namespace xbase
{

	const char column_name_parser::s_colon_char = ':';
	const char column_name_parser::s_star_char = '*';

	bool column_name_parser::match(const column_name_parser &other) const {
		if(m_any_column)
		{
			return true;
		}
		else if(m_any_qualifier)
		{
			const size_t inner_family_size = (m_colon - m_string_begin);
			const size_t other_family_size = (other.m_colon - other.m_string_begin);
			return ((inner_family_size == other_family_size)
				&& (std::char_traits<char>::compare(m_string_begin,
								    other.m_string_begin,
								    inner_family_size) == 0));
		}
		else
		{
			return ((m_size == other.m_size)
				&& (std::char_traits<char>::compare(m_string_begin,
								    other.m_string_begin,
								    m_size) == 0));
		}
	}

	bool column_name_parser::match(const char *column, std::size_t size) const {
		typedef std::char_traits<char> traits_type;
		if(m_any_column)
		{
			return true;
		}
		else if(m_any_qualifier) // 只比较列族名部分
		{
			const char * const colon_p = std::find(column,
							       column + size,
							       s_colon_char);
			// 若没有冒号，则会认为是列族名，用它来与列族名比较
			const size_t inner_family_size = (m_colon - m_string_begin);
			const size_t this_family_size = (colon_p - column);
			return ((inner_family_size == this_family_size)
				&& (traits_type::compare(m_string_begin,
							 column,
							 inner_family_size) == 0));
		}
		else
		{
			return ((m_size == size)
				&& (traits_type::compare(m_string_begin,
							 column,
							 m_size) == 0));
		}
	}

	void column_name_parser::parse() {
		// 首先判断是否任意列（“*”）
		m_any_column = ((m_size == 1) && (*m_string_begin == s_star_char));

		// 如果没有冒号，则m_colon == false
		if(! m_any_column) // 若不是，则一定有冒号；容错：若没找到冒号，则会认为整个字符串都为列族名
		{
			m_colon = std::find(m_string_begin, m_string_end, s_colon_char);
			// 判断冒号后面是否有且仅有一个星号
			m_any_qualifier = ((m_colon != m_string_end) // 找到冒号
					   && (m_string_end == (m_colon + 1 + 1)) // 且大小与期望一样
					   && (*(m_colon + 1) == s_star_char)); // 且最后一个字符是星号
		}

		m_contain_regex = (m_any_column || m_any_qualifier);
	}

	int column_name_parser::name_cmp(const char *name_a, std::size_t size_a,
					 const char *name_b, std::size_t size_b) {
		typedef std::char_traits<char> traits_type;
		if(size_a == 0) // empty
		{
			return (size_b == 0)
				? 0 // equal
				: -1; // lt
		}
		else if(size_b == 0)
		{
			return 1;
		}
		else
		{
			const size_t min_size = (std::min)(size_a, size_b);
			return traits_type::compare(name_a,
						    name_b,
						    min_size);
		}
	}

} // namespace xbase
